#ifndef __C_NGISDATA_UDXNODE_H__
#define __C_NGISDATA_UDXNODE_H__

#include <stdio.h>
#include <string.h>
#include <vector>
#include "IUdxNode.h"
#include "UdxKernel.h"

namespace NGIS
{
	namespace Data
	{
		class CUdxNode : public IUdxNode
		{
		public:
			CUdxNode(IUdxNode* pParent, const char* pName, EKernelType pType);

			~CUdxNode(void);

			void createKernel(const char* pName, EKernelType pType);

		public:
			virtual const char* getName();

			virtual void setName(const char* pName);

			virtual IUdxKernel* getKernel();

			virtual int getChildNodeCount();

			virtual IUdxNode* getChildNode(int idx);

			virtual IUdxNode* addChildNode(const char* pName, EKernelType pType);

			virtual bool removeChildNode(IUdxNode* pNode);

			virtual bool removeChildNode(int idx);

			virtual bool validateSchema(Schema::IUdxNodeSchema* pSchema);

			virtual bool FormatToXmlStream(std::string& xmlStr);

			virtual bool FormatToJsonStream(std::string& jsonStr);

			static EKernelType getKernelTypeBySchema(Schema::ESchemaNodeType pSType)
			{
				if (pSType == Schema::ESchemaNodeType::EDTKT_INT)
					return EKT_INT;
				else if (pSType == Schema::ESchemaNodeType::EDTKT_REAL)
					return EKT_REAL;
				else if (pSType == Schema::ESchemaNodeType::EDTKT_STRING)
					return EKT_STRING;
				else if (pSType == Schema::ESchemaNodeType::EDTKT_VECTOR2)
					return EKT_VECTOR2;
				else if (pSType == Schema::ESchemaNodeType::EDTKT_VECTOR3)
					return EKT_VECTOR3;
				else if (pSType == Schema::ESchemaNodeType::EDTKT_VECTOR4)
					return EKT_VECTOR4;
				else if (pSType == (Schema::ESchemaNodeType::EDTKT_INT | Schema::ESchemaNodeType::EDTKT_LIST))
					return EKT_INT_LIST;
				else if (pSType == (Schema::ESchemaNodeType::EDTKT_REAL | Schema::ESchemaNodeType::EDTKT_LIST))
					return EKT_REAL_LIST;
				else if (pSType == (Schema::ESchemaNodeType::EDTKT_STRING | Schema::ESchemaNodeType::EDTKT_LIST))
					return EKT_STRING_LIST;
				else if (pSType == (Schema::ESchemaNodeType::EDTKT_VECTOR2 | Schema::ESchemaNodeType::EDTKT_LIST))
					return EKT_VECTOR2_LIST;
				else if (pSType == (Schema::ESchemaNodeType::EDTKT_VECTOR3 | Schema::ESchemaNodeType::EDTKT_LIST))
					return EKT_VECTOR3_LIST;
				else if (pSType == (Schema::ESchemaNodeType::EDTKT_VECTOR4 | Schema::ESchemaNodeType::EDTKT_LIST))
					return EKT_VECTOR4_LIST;
				else if (pSType == Schema::ESchemaNodeType::EDTKT_NODE)
					return EKT_NODE;
				else if (pSType == Schema::ESchemaNodeType::EDTKT_LIST)
					return EKT_LIST;
				else if (pSType == Schema::ESchemaNodeType::EDTKT_MAP)
					return EKT_MAP;
				else if (pSType == Schema::ESchemaNodeType::EDTKT_TABLE)
					return EKT_TABLE;
				return EKT_COUNT;
			}

		private:
			bool iterateAndValidateNode(IUdxNode* pDNode, Schema::IUdxNodeSchema* pSNode);

		protected:
			std::string								mName;
			IUdxKernel*							mKernel;
			std::vector<IUdxNode*>		mChildNodes;
			IUdxNode*							mParentDxNode;

			//////////////////////////////////////////////////////////////////////////
			friend class CUdxKernel;
			friend class CUdxKernelIntValue;
			friend class CUdxKernelRealValue;
			friend class CUdxKernelStringValue;
			friend class CUdxKernelVector2dValue;
			friend class CUdxKernelVector3dValue;
			friend class CUdxKernelVector4dValue;
			friend class CUdxKernelIntArray;
			friend class CUdxKernelRealArray;
			friend class CUdxKernelStringArray;
			friend class CUdxKernelVector2dArray;
			friend class CUdxKernelVector3dArray;
			friend class CUdxKernelVector4dArray;

		};
	}
}

#endif